package firstdaemon

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
)

// Daemonize creates a daemon process.
func daemonize() error {
	// First fork: create child process and exit parent
	cmd := exec.Command(os.Args[0], os.Args[1:]...)
	//cmd := exec.Command("tail", "-f", "/dev/null")
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Setsid: true, // Start a new session
	}
	cmd.Env = os.Environ()
	cmd.Dir = "."

	err := cmd.Start()
	if err != nil {
		return fmt.Errorf("first fork failed: %v", err)
	}

	fmt.Printf("Daemon started with PID: %d\n", cmd.Process.Pid)
	os.Exit(0) // 父进程退出，子进程继续运行
	return nil
}

// SetupLogging sets up logging to file.
// 配置日志记录到文件，以免守护进程的日志文件丢失
func setupLogging(logFile string) (*os.File, error) {
	f, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return nil, fmt.Errorf("failed to open log file: %v", err)
	}
	//defer f.Close()
	fmt.Println(f.Fd())
	log.SetOutput(f)
	log.SetFlags(log.LstdFlags | log.Lshortfile)

	return f, nil
}

// HandleSignals handles common signals.
// 监听并处理常见的终止信号，比如 SIGTERM和SIGINT，保证可以优雅的退出。
func handleSignals() {
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)

	go func() {
		for sig := range sigChan {
			log.Printf("Received signal: %v. Exiting...", sig)
			os.Exit(0)
		}
	}()
}

func Run(daemonMode bool) {
	//logFile := flag.String("log", "/tmp/mydaemon.log", "Log file path")

	if daemonMode {
		// 去掉 -d 避免进入创建子进程的死循环之中
		removeElementInPlace(os.Args, "-d")
		daemonize()
	}

	// Change working directory to root or another safe location
	// err := os.Chdir("/")
	// if err != nil {
	// 	log.Fatal("Failed to change working directory:", err)
	// }

	// // Reset file permission mask
	// syscall.Umask(0)

	// Redirect standard file descriptors
	//closeFiles()  // 关闭所有打开的文件描述符，避免泄露。
	//openDevNull() // 将标准输入、输出和错误重定向到 /dev/null，以避免干扰其他程序或占用资源。

	// Set up logging
	// osFile, err := setupLogging(*logFile)
	// if err != nil {
	// 	log.Println(err.Error())
	// }
	// defer osFile.Close()

	// // Handle common signals
	// handleSignals()

	log.Println("Daemon is running...")

	// 执行bash
	//err := syscall.Exec("/bin/tail", []string{"/bin/tail", "-f", "/dev/null"}, os.Environ())
	//err := syscall.Exec("/bin/bash", []string{"/bin/bash", "--noediting", "--norc", "--noprofile"}, os.Environ())
	err := syscall.Exec("/bin/bash", []string{"/bin/bash"}, os.Environ())
	if err != nil {
		log.Fatal(err)
	}

	/**
	// Main loop for the daemon process
	ticker := time.NewTicker(time.Second * 5)
	defer ticker.Stop()

	// 主函数逻辑：包含一个定时器来模拟周期性任务，实际应用中你可以替换为具体的工作逻辑。
	for {
		select {
		case <-ticker.C:
			log.Println("Working...")
			// Insert your actual work here
		}
	}
	*/
}

func removeElementInPlace(slice []string, elem string) []string {
	j := 0
	for _, item := range slice {
		if item != elem {
			slice[j] = item
			j++
		}
	}
	return slice[:j]
}

// closeFiles closes all open file descriptors.
func closeFiles() {
	const maxFD = 1024
	for fd := 0; fd < maxFD; fd++ {
		syscall.Close(fd)
	}
}

// openDevNull opens /dev/null for standard input, output, and error.
func openDevNull() {
	devNull, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
	if err != nil {
		log.Fatal("Failed to open /dev/null:", err)
	}
	os.Stdin = devNull
	os.Stdout = devNull
	os.Stderr = devNull
}
